package com.lyw.gulimall.ware.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lyw.common.constant.WareConstant;
import com.lyw.common.utils.R;
import com.lyw.gulimall.ware.dao.PurchaseDetailDao;
import com.lyw.gulimall.ware.entity.PurchaseDetailEntity;
import com.lyw.gulimall.ware.entity.PurchaseDetailErrorEntity;
import com.lyw.gulimall.ware.feign.ProductFeignService;
import com.lyw.gulimall.ware.service.PurchaseDetailErrorService;
import com.lyw.gulimall.ware.service.PurchaseDetailService;
import com.lyw.gulimall.ware.service.WareSkuService;
import com.lyw.gulimall.ware.vo.MergePurchaseListVo;
import com.lyw.gulimall.ware.vo.PurchaseDetail;
import com.lyw.gulimall.ware.vo.PurchaseDoneVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lyw.common.utils.PageUtils;
import com.lyw.common.utils.Query;

import com.lyw.gulimall.ware.dao.PurchaseDao;
import com.lyw.gulimall.ware.entity.PurchaseEntity;
import com.lyw.gulimall.ware.service.PurchaseService;
import org.springframework.transaction.annotation.Transactional;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired
    private ProductFeignService productFeignService;

    @Autowired
    private PurchaseDetailErrorService purchaseDetailErrorService;

    @Autowired
    private PurchaseDetailService purchaseDetailService;

    @Autowired
    private WareSkuService wareSkuService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public IPage<PurchaseEntity> queryUnReceivePurchaseListPage(Integer page, Integer limit) {
        Page<PurchaseEntity> result = new Page<>(page, limit);
        QueryWrapper<PurchaseEntity> lqw = new QueryWrapper<>();
        lqw.eq("status", 0).or().eq("status", 1);

        Page<PurchaseEntity> pages = baseMapper.selectPage(result, lqw);
        return pages;
    }

    @Override
    @Transactional
    public void mergePurchaseList(MergePurchaseListVo mergePurchaseListVo) {
        Long purchaseId = mergePurchaseListVo.getPurchaseId();

        if (purchaseId == null) {
            // 1、没有指定合并的清单，新建一个
            PurchaseEntity entity = new PurchaseEntity();

            // 设置为新建状态
            entity.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getCode());
            entity.setCreateTime(new Date());
            entity.setUpdateTime(new Date());
            this.save(entity);
            purchaseId = entity.getId();
        }
        List<Long> items = mergePurchaseListVo.getItems();

        // 合并就是修改采购细节表中的 purchaseId
        Long finalPurchaseId = purchaseId;
        List<PurchaseDetailEntity> detailEntities = items.stream().map(item -> {

            PurchaseDetailEntity detailEntity = purchaseDetailService.getById(item);
            // 判断当前采购需求是否是新建状态
            if (detailEntity.getStatus() == WareConstant.PurchaseDetailsStatusEnum.CREATED.getCode() || detailEntity.getStatus() == WareConstant.PurchaseDetailsStatusEnum.ASSIGNED.getCode()) {
                detailEntity.setPurchaseId(finalPurchaseId);
                // 设置状态为已分配
                detailEntity.setStatus(WareConstant.PurchaseDetailsStatusEnum.ASSIGNED.getCode());
            }
            return detailEntity;
        }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(detailEntities);

        PurchaseEntity entity = new PurchaseEntity();
        entity.setId(finalPurchaseId);
        entity.setUpdateTime(new Date());
        this.updateById(entity);
    }

    @Override
    @Transactional
    public IPage<PurchaseEntity> getUserPurchaseLists(Integer page, Integer limit, List<Long> purchaseIds) {
        // 1、找到当前员工 已分配 的采购单
        Page<PurchaseEntity> result = new Page<>(page, limit);
        LambdaQueryWrapper<PurchaseEntity> lqw = new LambdaQueryWrapper<>();
        lqw.in(PurchaseEntity::getId, purchaseIds)
                // 领取采购单是已分配的
                .eq(PurchaseEntity::getStatus, WareConstant.PurchaseStatusEnum.ASSIGNED.getCode());

        IPage<PurchaseEntity> pages = baseMapper.selectPage(result, lqw);

        // 2、修改当前员工采购单的状态
        List<PurchaseEntity> purchaseEntities = pages.getRecords().stream().map(item -> {
            item.setStatus(WareConstant.PurchaseStatusEnum.RECEIVED.getCode());
            item.setUpdateTime(new Date());
            return item;
        }).collect(Collectors.toList());
        this.updateBatchById(purchaseEntities);
        pages.setRecords(purchaseEntities);

        // 3、修改采购需求的状态
        purchaseEntities.forEach(item -> {
            purchaseDetailService.changeDetailListStatusByPurchaseId(item.getId());
        });
        return pages;
    }

    @Override
    @Transactional
    public void done(PurchaseDoneVo purchaseDoneVo) {

        Long purchaseId = purchaseDoneVo.getId();

        // 2、改变采购单中每个采购需求的状态
        List<PurchaseDetail> items = purchaseDoneVo.getItems();
        List<PurchaseDetailEntity> updates = new ArrayList<>();

        boolean flag = true;
        for (PurchaseDetail item : items) {
            PurchaseDetailEntity entity = purchaseDetailService.getById(item.getItemId());
            // R info = productFeignService.info(entity.getSkuId());

            PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
            detailEntity.setId(item.getItemId());

            if (item.getStatus() == WareConstant.PurchaseDetailsStatusEnum.HASERROR.getCode()) {

                flag = false;
                PurchaseDetailErrorEntity errorEntity = new PurchaseDetailErrorEntity();
                errorEntity.setPurchaseDetailId(item.getItemId());
                errorEntity.setReason(item.getReason());
                errorEntity.setNeedCount(entity.getSkuNum());
                errorEntity.setPurchaseDetailCount(item.getPurchaseCount());
                errorEntity.setPurchaseDetailPrice(item.getPurchasePrice());

                // 保存采购需求采购失败的信息
                purchaseDetailErrorService.save(errorEntity);

                // 改变采购需求的状态信息
                detailEntity.setStatus(item.getStatus());
            } else {
                // 改变采购需求中的状态为已完成
                detailEntity.setStatus(WareConstant.PurchaseStatusEnum.FINISHED.getCode());
                // 3、将完成采购需求的采购项进行入库
                wareSkuService.addStock(entity.getSkuId(), entity.getWareId(), entity.getSkuNum());
            }
            updates.add(detailEntity);
        }

        purchaseDetailService.updateBatchById(updates);

        // 1、改变采购单状态
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(purchaseId);
        purchaseEntity.setStatus(flag ? WareConstant.PurchaseStatusEnum.FINISHED.getCode() : WareConstant.PurchaseStatusEnum.HASERROR.getCode());
        purchaseEntity.setUpdateTime(new Date());

        this.updateById(purchaseEntity);

        // 4、将不成功的重新发回到新建状态，并且没有被合并
    }

    @Override
    public IPage<Map<String, Object>> queryPageByCondition(Integer page, Integer limit, String key, Integer status) {
        Page<PurchaseEntity> result = new Page<>(page, limit);
        LambdaQueryWrapper<PurchaseEntity> lqw = new LambdaQueryWrapper<>();

        if (StringUtils.isNotBlank(key)) {
            lqw.and(wrapper -> {
                wrapper.eq(PurchaseEntity::getId, key).or().like(PurchaseEntity::getAssigneeName, key);
            });
        }

        if (status != null) {
            lqw.eq(PurchaseEntity::getStatus, status);
        }

        return baseMapper.selectPurchaseListPage(result, lqw);
    }
}